﻿using AutoFlatnessTest.Db;
using AutoFlatnessTest.Db.Tables;
using AutoFlatnessTest.Plc;
using AutoFlatnessTest.ViewModel;
using Ping9719.WpfEx;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace AutoFlatnessTest
{
    /// <summary>
    /// UcHome.xaml 的交互逻辑
    /// </summary>
    public partial class UcHome : UserControlBase
    {
        public UcHomeVModel VModel = new UcHomeVModel();
        string selectedId = null;

        public UcHome()
        {
            InitializeComponent();
            //string madsata = Encoding.Default.GetString(new byte[1]);
            //if (string.IsNullOrWhiteSpace(madsata))
            //{
            //    string ss = madsata;
            //}
            this.DataContext = VModel;
        }

        private void load(object sender, EventArgs e)
        {
            if (!this.IsInDesignMode)
            {
                VModel.InputVal = ConModel.Data.InputVal;
                VModel.CcVal = ConModel.Data.ExtrVal;
                VModel.Proj = ProjectDb.GetNamsAll(true).ToDictionary(k => k.Id, v => v.Name);

                var state = InovanceRun.GetState();
                if (state == 1 || state == 2)
                    VModel.IsStart = true;
            }
        }


        CancellationTokenSource tokenSource;
        CancellationToken token;
        private void Button_ClickQd(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(selectedId))
            {
                MessageBox.Show("请选择项目");
                return;
            }
            if (string.IsNullOrWhiteSpace(VModel.WorkOrde))
            {
                MessageBox.Show("请填写工单");
                return;
            }
            if (VModel.MoShi == MoShi.录入 && VModel.InputValSelect == null)
            {
                MessageBox.Show("请选择录入的值");
                return;
            }

            tokenSource = new CancellationTokenSource();
            token = tokenSource.Token;

            Task.Run(() => Run(token), token);
        }

        private void Button_ClickJs(object sender, RoutedEventArgs e)
        {
            StopAll(false);
        }

        private void selectChang(object sender, SelectionChangedEventArgs e)
        {
            //comBox

            selectedId = ((ComboBox)sender).SelectedValue?.ToString();

            if (selectedId == null)
            {
                tbInfo.DatasClear();
            }
            else
            {
                var proj = ProjectDb.Get(selectedId);
                tbInfo.DatasSet(proj.RowNum ?? 0, proj.ColumnNum ?? 0);
            }
        }

        private void Run(CancellationToken ct)
        {
            try
            {
                int choujiannumber = 0;
                VModel.Info1 = "启动中...";
                VModel.IsStart = true;
                int oknumber = 0;
                //界面数据
                var proj = ProjectDb.Get(selectedId);
                //重新刷新界面
                tbInfo.DatasSet(proj.RowNum ?? 0, proj.ColumnNum ?? 0);
                //VModel.Number = TestRecordDb.GetChouChe(proj.Name, VModel.WorkOrde).ToString();
                try
                {
                    InovanceRun.Plc.SetData<Int16>(InovanceComm.模式, 2);
                    Thread.Sleep(100);
                    InovanceRun.Plc.SetData<Int16>(InovanceComm.启动, 2);
                }
                catch (Exception ex)
                {
                    throw new Exception("无法连接到PLC");
                }

                InovanceRun.LoadData(proj, VModel.MoShi);

                TestRecord testRecord = new TestRecord();
                testRecord.ProjectId = selectedId;
                testRecord.ProjectName = proj.Name;
                testRecord.WorkOrder = VModel.WorkOrde;

                int num = 1;
                if (VModel.MoShi == MoShi.标准 || VModel.MoShi == MoShi.抽测)
                {
                    if (VModel.MoShi == MoShi.抽测)
                    {
                        //oknumber = TestRecordDb.GetChouChe(proj.Name, VModel.WorkOrde);
                        //VModel.Number = oknumber.ToString()+"/"+choujiannumber.ToString();
                        int sl = 0;
                        if (!int.TryParse(VModel.RiCount, out sl))
                            throw new Exception("抽测总数量不是有效的数字");
                        if (sl <= 0)
                            throw new Exception("抽测总数量需要大于0");

                        try
                        {
                            MesExtractionDb.AddUpdata(new MesExtraction()
                            {
                                ProjectName = testRecord.ProjectName,
                                WorkOrder = testRecord.WorkOrder,
                                CountAll = sl,
                                ExtractionPer = Convert.ToInt32(VModel.CcValSelect.Replace("%", "")),
                            });
                        }
                        catch (Exception ex)
                        {
                            throw new Exception($"无法连接到数据库，请检查网络。\r\n{ex.Message}");
                        }
                        int ccval= Convert.ToInt32(VModel.CcValSelect.Replace("%", ""));
                        choujiannumber = sl*ccval/100;
                        int csyouyu = sl*ccval%100;
                        if (csyouyu>0)
                        {
                            choujiannumber = choujiannumber+1;
                        }
                        oknumber = TestRecordDb.GetChouChe(proj.Name, VModel.WorkOrde);
                        VModel.Number = oknumber.ToString()+"/"+choujiannumber.ToString();
                    }

                    ////扫描切换模式
                    //var mams = JiEnShiRun.DeviceSma.Send(JiEnShiRun.单板);
                    //if (!mams.ToLower().Contains("ok"))
                    //{
                    //    throw new Exception("扫码枪切换模式失败，请联系管理员");
                    //}
                    //oknumber = TestRecordDb.GetChouChe(proj.Name, VModel.WorkOrde);
                    //VModel.Number = oknumber.ToString()+"/"+choujiannumber.ToString();
                    //无限的板子
                    while (true)
                    {
                        testRecord.GuidId = DbHelp.ExplicitKey;
                        //VModel.Number = TestRecordDb.GetChouChe().ToString();
                        //取消任务检测
                        if (ct.IsCancellationRequested)
                            ct.ThrowIfCancellationRequested();

                        //板子上的待测试物品
                        for (int r = 1; r <= proj.RowNum; r++)
                        {
                            for (int c = 1; c <= proj.ColumnNum; c++)
                            {
                                if (num == 1)
                                    VModel.Info1 = $"准备中【{num}】，请按下操作台右下绿色启动按钮...";
                                else
                                    VModel.Info1 = $"准备中【{num}】...";

                                while (true)
                                {
                                    //取消任务检测
                                    if (ct.IsCancellationRequested)
                                        ct.ThrowIfCancellationRequested();

                                    try
                                    {
                                        if (InovanceRun.Plc.GetData<Int16>(InovanceComm.单板测试准备好) == 2)
                                        {
                                            if (num == 1)
                                                //重新刷新界面
                                                tbInfo.DatasSet(proj.RowNum ?? 0, proj.ColumnNum ?? 0);

                                            break;
                                        }
                                    }
                                    catch (Exception)
                                    {

                                    }

                                    Thread.Sleep(200);
                                }

                                //当前进行中
                                var ui = tbInfo.Datas.FirstOrDefault(o => o.Row == r && o.Column == c);

                                VModel.Info1 = $"任务中【{num}】...";
                                ui.Data.VModel.SetState(BoardMinState.进行中);

                                string madata = string.Empty;
                                string midata = string.Empty;
                                //扫码线程
                                var t1 = Task.Run(() =>
                                {
                                    if (proj.IsSma != 1)
                                        return;

                                    //扫码
                                    madata = JiEnShiRun.DeviceSma.SendWait(JiEnShiRun.SmaGo).Trim();
                                    //没有扫码数据
                                    if (string.IsNullOrEmpty(madata))
                                        JiEnShiRun.DeviceSma.SendWait(JiEnShiRun.SmaEnd);
                                });
                                //扫描线程
                                var t2 = Task.Run(() =>
                                {
                                    //扫描
                                    var mi = JiEnShiRun.DeviceSmi.Send(JiEnShiRun.SmiGo);
                                    //开始移动
                                    int i1 = 0;
                                    while (true)
                                    {
                                        //取消任务检测
                                        if (ct.IsCancellationRequested)
                                            ct.ThrowIfCancellationRequested();

                                        try
                                        {
                                            InovanceRun.Plc.SetData<Int16>(InovanceComm.单板测试开始, 2);
                                            break;
                                        }
                                        catch (Exception)
                                        {
                                            i1++;
                                            VModel.Info1 = $"通知PLC开始失败，正在重试{i1}...";
                                        }

                                        Thread.Sleep(200);
                                    }
                                    
                                    Thread.Sleep(500);
                                    //扫描数据 94.118,+00000.000,+00000.000
                                    //扫描数据 94.118,+00000.000,+00000.000,+00000.000,+00000.000 芯片平面度
                                    midata = JiEnShiRun.DeviceSmi.Recmes();

                                    //如果没有接收到返回值 就再次等待
                                    if (string.IsNullOrWhiteSpace(midata) || midata.Contains("T1"))
                                        //扫描数据 94.118,+00000.000,+00000.000
                                        midata = JiEnShiRun.DeviceSmi.Recmes();
                                });

                                //等待完成
                                Task.WaitAll(t1, t2);

                                //取消任务检测
                                if (ct.IsCancellationRequested)
                                    ct.ThrowIfCancellationRequested();

                                var maobj = MiData.GetMiData(midata);

                                bool isok = false;
                                //不合格
                                if (maobj.IsNull || (proj.IsSma == 1 && string.IsNullOrEmpty(madata)) || maobj.DiffVal >= proj.OkVal || (proj.OkValWarn.HasValue && proj.OkValWarn > 0 && maobj.ChipDiffVal >= proj.OkValWarn))
                                {
                                    ui.Data.VModel.SetState(BoardMinState.未通过, maobj.IsNull ? "扫描错误" : maobj.DiffVal.ToString(), madata == string.Empty ? "无二维码信息" : madata);
                                }
                                else
                                {
                                    //过站拦截
                                    if (proj.IsCheck == 1 && !XNJC_CheckDb.IsChe(madata))
                                    {
                                        ui.Data.VModel.SetState(BoardMinState.未通过, "过站拦截", madata);
                                        isok = false;
                                    }
                                    else
                                    {
                                        ui.Data.VModel.SetState(BoardMinState.通过, $"{maobj.DiffVal.ToString()};{maobj.ChipDiffVal.ToString()}", madata);
                                        isok = true;
                                    }
                                }

                                ui.Data.VModel.TxtValTip = $@"相似度：{maobj.Simi}
差值：{maobj.DiffVal}
最大值：{maobj.MaxVal}
最小值：{maobj.MinVal}
原始信息：{midata.Trim()}
IsSma：{proj.IsSma}
扫描信息：{madata}";

                                //有了数据后 告诉plc完成
                                int i = 0;
                                while (true)
                                {
                                    //取消任务检测
                                    if (ct.IsCancellationRequested)
                                        ct.ThrowIfCancellationRequested();

                                    try
                                    {
                                        InovanceRun.Plc.SetData<Int16>(InovanceComm.单板测试完成, 2);
                                        break;
                                    }
                                    catch (Exception)
                                    {
                                        i++;
                                        VModel.Info1 = $"通知PLC完成失败，正在重试{i}...";
                                    }

                                    Thread.Sleep(200);
                                }
                                

                                //记录数据
                                testRecord.RowNum = r;
                                testRecord.ColumnNum = c;
                                testRecord.TestNum = num;
                                testRecord.IsOk = isok ? 1 : 2;
                                testRecord.MiSimi = maobj.Simi;
                                testRecord.MiMaxVal = maobj.MaxVal;
                                testRecord.MiMinVal = maobj.MinVal;
                                testRecord.MiVal = maobj.DiffVal;
                                testRecord.MiInfo = midata.Trim();
                                testRecord.MaInfo = madata;
                                testRecord.Mode = (int)VModel.MoShi;
                                TestRecordDb.Add(testRecord);

                                num++;
                            }
                        }
                        if (VModel.MoShi == MoShi.抽测)
                        {

                            oknumber = TestRecordDb.GetChouChe(proj.Name, VModel.WorkOrde);
                            VModel.Number = oknumber.ToString()+"/"+choujiannumber.ToString();
                            //VModel.Number = TestRecordDb.GetChouChe(proj.Name, VModel.WorkOrde).ToString();
                            if (choujiannumber<=oknumber)
                            {
                                MessageBox.Show($"抽测{VModel.Number}个，目标{choujiannumber}个", "抽测");
                            }
                        }
                        num = 1;

                    }
                }
                else if (VModel.MoShi == MoShi.极速)
                {
                    //    //扫描切换模式
                    //    var mams = JiEnShiRun.DeviceSma.Send(JiEnShiRun.连续);
                    //    if (mams != "ok")
                    //    {
                    //        throw new Exception("扫码枪切换模式失败，请联系管理员");
                    //    }

                    //    //无限的板子
                    //    while (true)
                    //    {
                    //        //取消任务检测
                    //        if (ct.IsCancellationRequested)
                    //            ct.ThrowIfCancellationRequested();

                    //        //板子上的待测试物品
                    //        for (int r = 1; r <= proj.RowNum; r++)
                    //        {
                    //            if (num == 1)
                    //                VModel.Info1 = $"准备中【{num}】，请按下操作台右下绿色启动按钮...";
                    //            else
                    //                VModel.Info1 = $"准备中【{num}】...";

                    //            while (true)
                    //            {
                    //                //取消任务检测
                    //                if (ct.IsCancellationRequested)
                    //                    ct.ThrowIfCancellationRequested();

                    //                if (InovanceRun.Plc.GetData<Int16>(InovanceComm.连续测试准备好) == 2)
                    //                {
                    //                    if (num == 1)
                    //                        //重新刷新界面
                    //                        tbInfo.DatasSet(proj.RowNum ?? 0, proj.ColumnNum ?? 0);

                    //                    break;
                    //                }

                    //                Thread.Sleep(200);
                    //            }

                    //            var ui = tbInfo.Datas.Where(o => o.Row == r);
                    //            foreach (var item in ui)
                    //            {
                    //                item.Data.VModel.SetState(BoardMinState.准备);
                    //            }

                    //            VModel.Info1 = $"任务中【{num}】...";

                    //            foreach (var item in ui)
                    //            {
                    //                item.Data.VModel.SetState(BoardMinState.进行中);
                    //            }

                    //            string midata = string.Empty;
                    //            List<string> madata = new List<string>();

                    //            //连续扫码状态跟踪
                    //            var tokenSource = new CancellationTokenSource();
                    //            var token = tokenSource.Token;

                    //            //扫码
                    //            var t1 = Task.Run(() =>
                    //            {
                    //                JiEnShiRun.DeviceSma.Send(JiEnShiRun.SmaGo);
                    //                madata = JiEnShiRun.DeviceSma.WaitInfo(token);
                    //                JiEnShiRun.DeviceSma.Send(JiEnShiRun.SmaEnd);
                    //            });

                    //            //扫描
                    //            var t2 = Task.Run(() =>
                    //            {
                    //                //扫描
                    //                var mi = JiEnShiRun.DeviceSmi.Send(JiEnShiRun.SmiGo);
                    //                //扫描数据
                    //                midata = JiEnShiRun.DeviceSmi.Recmes();

                    //                //请求取消连续扫码
                    //                Thread.Sleep(200);
                    //                tokenSource.Cancel();
                    //            });

                    //            InovanceRun.Plc.SetData<Int16>(InovanceComm.连续测试开始, 2);

                    //            //等待 扫码 扫描 完成
                    //            Task.WaitAll(t1, t2);

                    //            foreach (var item in ui)
                    //            {
                    //                item.Data.VModel.SetState(BoardMinState.通过, "0.01", "asd12315");
                    //            }

                    //            //有了数据后 告诉plc完成
                    //            InovanceRun.Plc.SetData<Int16>(InovanceComm.连续测试完成, 2);

                    //            tokenSource.Dispose();
                    //            num++;
                    //        }

                    //        num = 1;
                    //    }

                }
                else if (VModel.MoShi == MoShi.录入)
                {
                    ////扫描切换模式
                    //var mams = JiEnShiRun.DeviceSma.Send(JiEnShiRun.单板);
                    //if (!mams.ToLower().Contains("ok"))
                    //{
                    //    throw new Exception("扫码枪切换模式失败，请联系管理员");
                    //}

                    //无限的板子
                    while (true)
                    {
                        testRecord.GuidId = DbHelp.ExplicitKey;

                        //取消任务检测
                        if (ct.IsCancellationRequested)
                            ct.ThrowIfCancellationRequested();

                        //板子上的待测试物品
                        for (int r = 1; r <= proj.RowNum; r++)
                        {
                            for (int c = 1; c <= proj.ColumnNum; c++)
                            {
                                if (num == 1)
                                    VModel.Info1 = $"准备中【{num}】，请按下操作台右下绿色启动按钮...";
                                else
                                    VModel.Info1 = $"准备中【{num}】...";

                                while (true)
                                {
                                    //取消任务检测
                                    if (ct.IsCancellationRequested)
                                        ct.ThrowIfCancellationRequested();

                                    try
                                    {
                                        if (InovanceRun.Plc.GetData<Int16>(InovanceComm.单板测试准备好) == 2)
                                        {
                                            if (num == 1)
                                                //重新刷新界面
                                                tbInfo.DatasSet(proj.RowNum ?? 0, proj.ColumnNum ?? 0);

                                            break;
                                        }
                                        VModel.Info1 = $"准备中【{num}】...";
                                    }
                                    catch (Exception)
                                    {

                                    }

                                    Thread.Sleep(200);
                                }

                                //当前进行中
                                var ui = tbInfo.Datas.FirstOrDefault(o => o.Row == r && o.Column == c);

                                VModel.Info1 = $"任务中【{num}】...";
                                ui.Data.VModel.SetState(BoardMinState.进行中);

                                string madata = string.Empty;
                                string midata = string.Empty;

                                //开始移动
                                int i = 0;
                                while (true)
                                {
                                    //取消任务检测
                                    if (ct.IsCancellationRequested)
                                        ct.ThrowIfCancellationRequested();

                                    try
                                    {
                                        InovanceRun.Plc.SetData<Int16>(InovanceComm.单板测试开始, 2);
                                        break;
                                    }
                                    catch (Exception)
                                    {
                                        i++;
                                        VModel.Info1 = $"通知PLC开始失败，正在重试{i}...";
                                    }

                                    Thread.Sleep(200);
                                }

                                //扫码
                                madata = JiEnShiRun.DeviceSma.SendWait(JiEnShiRun.SmaGo).Trim();
                                //没有扫码数据
                                if (string.IsNullOrEmpty(madata))
                                    JiEnShiRun.DeviceSma.SendWait(JiEnShiRun.SmaEnd);

                                //取消任务检测
                                if (ct.IsCancellationRequested)
                                    ct.ThrowIfCancellationRequested();

                                //没有扫码数据
                                if (string.IsNullOrEmpty(madata))
                                {
                                    ui.Data.VModel.SetState(BoardMinState.未通过, "录入失败", "无二维码信息");
                                }
                                //过站拦截
                                else if (proj.IsCheck == 1 && !XNJC_CheckDb.IsChe(madata))
                                {
                                    ui.Data.VModel.SetState(BoardMinState.未通过, "过站拦截", madata);
                                }
                                else
                                {
                                    //记录数据
                                    testRecord.RowNum = r;
                                    testRecord.ColumnNum = c;
                                    testRecord.TestNum = num;
                                    testRecord.IsOk = VModel.IsLrmsOk ? 1 : 2;
                                    testRecord.MiSimi = null;
                                    testRecord.MiMaxVal = null;
                                    testRecord.MiMinVal = null;
                                    testRecord.MiVal = VModel.InputValSelect;
                                    testRecord.MiInfo = null;
                                    testRecord.MaInfo = madata;
                                    testRecord.Mode = (int)VModel.MoShi;
                                    TestRecordDb.Add(testRecord);

                                    ui.Data.VModel.SetState(BoardMinState.通过, "已录入", madata);
                                }

                                //有了数据后 告诉plc完成
                                int i1 = 0;
                                while (true)
                                {
                                    //取消任务检测
                                    if (ct.IsCancellationRequested)
                                        ct.ThrowIfCancellationRequested();

                                    try
                                    {
                                        InovanceRun.Plc.SetData<Int16>(InovanceComm.单板测试完成, 2);
                                        break;
                                    }
                                    catch (Exception)
                                    {
                                        i++;
                                        VModel.Info1 = $"通知PLC完成失败，正在重试{i1}...";
                                    }

                                    Thread.Sleep(200);
                                }

                                num++;
                            }
                        }

                        num = 1;
                    }
                }

                VModel.Info1 = $"已完成";
                StopAll(true);
            }
            //手动取消引发的错误
            catch (OperationCanceledException ex)
            {

            }
            catch (Exception ex)
            {
                MessageBox.Show("出现错误：" + ex.ToString());
                MessageBox.Show("点击【确定】停止");
                StopAll(false);
            }
        }

        void StopAll(bool isok)
        {
            try
            {
                if (!isok)
                    VModel.Info1 = $"正在停止...";

                if (tokenSource != null && !tokenSource.IsCancellationRequested)
                {
                    tokenSource?.Cancel();
                    tokenSource?.Dispose();
                }

                if (!isok)
                {
                    InovanceRun.Plc.SetData<Int16>(InovanceComm.停止, 2);
                    VModel.Info1 = $"已停止";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("停止失败" + ex.Message);
            }
            finally
            {
                VModel.IsStart = false;
                VModel.Info1 = $"已停止";
            }
        }

        private void ccchan(object sender, RoutedEventArgs e)
        {
            var aaaa = (System.Windows.Controls.Primitives.ToggleButton)sender;
            if (aaaa.IsChecked == true)
            {
                try
                {
                    var proj = ProjectDb.Get(selectedId);
                    var aaa = MesExtractionDb.Get(new MesExtraction()
                    {
                        ProjectName = proj.Name,
                        WorkOrder = VModel.WorkOrde,
                    });

                    if (aaa != null)
                    {
                        VModel.RiCount = aaa.CountAll?.ToString();
                        VModel.CcValSelect = $"{aaa.ExtractionPer}%";
                    }
                }
                catch
                {

                }
            }
        }
    }
}
